package com.itheima.health.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.health.common.MessageConst;
import com.itheima.health.common.RedisConst;
import com.itheima.health.dao.*;
import com.itheima.health.entity.PageResult;
import com.itheima.health.entity.QueryPageBean;
import com.itheima.health.pojo.*;
import com.itheima.health.service.SetMealService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;


@Slf4j
@DubboService
public class SetMealServiceImpl implements SetMealService {

    @Autowired
    private SetMealDao setMealDao;
    @Autowired
    private SetMealCheckGroupDao setMealCheckGroupDao;
    @Autowired
    private CheckGroupDao checkGroupDao;
    @Autowired
    private CheckGroupItemDao checkGroupItemDao;
    @Autowired
    private CheckItemDao checkItemDao;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public PageResult findPage(QueryPageBean queryPageBean) {
        /*
         * @Date: 10:41 上午 2021/1/6
         * @param: [queryPageBean]
         * @return: com.itheima.health.entity.PageResult
         * @Description: 使用PageHelper插件获取分页信息
         * 使用redis进行存储
         */
        PageHelper.startPage(queryPageBean.getCurrentPage(), queryPageBean.getPageSize());
        //使用selectByExample获取分页数据
        String queryString = queryPageBean.getQueryString();
        Example example = new Example(Setmeal.class);
        Example.Criteria criteria = example.createCriteria();
        //判断非空才进行模糊查询
        if (!StringUtils.isEmpty(queryString)) {
            String like = "%" + queryString + "%";
            criteria.orLike("code", like);
            criteria.orLike("name", like);
            criteria.orLike("helpCode", like);
        }
        Page<Setmeal> page = (Page<Setmeal>) setMealDao.selectByExample(example);
        //使用编写SQL方式
        //Page<Setmeal> page = setMealDao.findPage(queryPageBean.getQueryString());
        return new PageResult(page.getTotal(), page.getResult());

    }

    @Transactional
    @Override
    public boolean add(Setmeal setmeal, Integer[] checkGroupIds) {
        /*
         * @Date: 3:50 下午 2021/1/6
         * @param: [setmeal, ids]
         * @return: boolean
         * @Description: 判断套餐添加成功，检查组有数据时才会进行添加数据
         */
        boolean flag = false;
        int insertCount = setMealDao.insert(setmeal);

        //当添加套餐成功并且检查组有数据时，才进行检查组的添加
        if (insertCount > 0) {
            //向上提取出来，多次new对象会影响效率
            SetmealCheckgroup setmealCheckgroup = new SetmealCheckgroup();
            setmealCheckgroup.setSetmealId(setmeal.getId());
            for (Integer checkGroupId : checkGroupIds) {
                //使用tk-mybatis循环插入数据
                setmealCheckgroup.setCheckgroupId(checkGroupId);
                setMealCheckGroupDao.insertSelective(setmealCheckgroup);
            }
            flag = true;
        }
        return flag;
    }

    @Override
    public Integer imgCount(String fileName) {
        Setmeal setmeal = new Setmeal();
        setmeal.setImg(fileName);
        return setMealDao.selectCount(setmeal);
    }

    @Override
    public List<Setmeal> findAll() {
        List<Setmeal> setmeals = null;
        //判断redis中有无setmeal这个key
        if (!redisTemplate.hasKey(RedisConst.FIND_SETMEAL_ALL)) {
            //没有
            setmeals = setMealDao.selectAll();
            redisTemplate.boundValueOps(RedisConst.FIND_SETMEAL_ALL).set(setmeals);
        } else {
            setmeals = (List<Setmeal>) redisTemplate.boundValueOps(RedisConst.FIND_SETMEAL_ALL).get();
        }
        return setmeals;
    }

    @Override
    public Setmeal findById(Integer id) {
        /*
         * @Date: 3:14 下午 2021/1/11
         * @param: [id]
         * @return: com.itheima.health.pojo.Setmeal
         * @Description: 查询套餐，检查组和检查项
         * 1、根据SetMeal查询setMealCheckGroup中间表
         * 2、查询SetMealCheckGroup中间表得CheckGroup
         * 3、根据CheckGroup查询CheckGroupItem中间表
         * 4、查询CheckGroupItem中间表得到CheckItem
         * 5、封装CheckItem到容器中，并存入CheckGroup
         * 6、封装CheckGroup到容器中，并存入SetMeal
         */

        Setmeal setmeal = null;
        if (redisTemplate.boundHashOps(RedisConst.FIND_SETMEAL_DETAIL).get(id) == null) {
            setmeal = setMealDao.selectByPrimaryKey(id);
            //查询setMealCheckGroup中间表得到setMealCheckGroupList
            SetmealCheckgroup setmealCheckgroup = new SetmealCheckgroup();
            setmealCheckgroup.setSetmealId(setmeal.getId());
            List<SetmealCheckgroup> setMealCheckGroupList = setMealCheckGroupDao.select(setmealCheckgroup);
            //创建CheckGroup容器
            ArrayList<CheckGroup> checkGroupList = new ArrayList<>();
            //遍历setMealCheckGroupList得到每个setMealCheckgroup
            for (SetmealCheckgroup setMealCheckgroup : setMealCheckGroupList) {
                //查询setMealCheckgroup中间表得到checkGroupId，再根据checkGroupId得到每个checkGroup
                Integer checkGroupId = setMealCheckgroup.getCheckgroupId();
                CheckGroup checkGroup = checkGroupDao.selectByPrimaryKey(checkGroupId);
                //查询checkGroupItem中间表，根据CheckgroupId得到checkGroupItemList
                CheckGroupItem checkGroupItem = new CheckGroupItem();
                checkGroupItem.setCheckgroupId(checkGroup.getId());
                List<CheckGroupItem> checkGroupItemList = checkGroupItemDao.select(checkGroupItem);
                //创建CheckItem容器
                ArrayList<CheckItem> checkItemList = new ArrayList<>();
                //遍历checkGroupItemList得到每个checkGroupItem并取出checkItemId，根据checkItemId得到每个CheckItem
                for (CheckGroupItem groupItem : checkGroupItemList) {
                    CheckItem checkItem = checkItemDao.selectByPrimaryKey(groupItem.getCheckitemId());
                    //把checkItem存入容器中
                    checkItemList.add(checkItem);
                }
                //把checkItem容器存入checkGroup中
                checkGroup.setCheckItems(checkItemList);
                //把checkGroup存入checkGroup容器中
                checkGroupList.add(checkGroup);
            }
            //把checkGroup容器存入setMeal中并返回
            setmeal.setCheckGroups(checkGroupList);
            redisTemplate.boundHashOps(RedisConst.FIND_SETMEAL_DETAIL).put(id, setmeal);
        } else {
            setmeal = (Setmeal) redisTemplate.boundHashOps(RedisConst.FIND_SETMEAL_DETAIL).get(id);
        }
        return setmeal;
    }
}
